﻿using System;
using System.IO.IsolatedStorage;
using System.Windows;
using VisualStock.Infrastructure;
using VisualStock.Infrastructure.Converters;
using VisualStock.Infrastructure.Models;
using VisualStock.Modules.StockMarket.DownloadServiceReference;
using System.IO;

namespace VisualStock.Modules.StockMarket.Services
{
    public partial class HistoricalDataService
    {
        public const string ISOLATED_STORAGE_DIRECTORY = "HistoricalStockData";

        /// <summary>
        /// Download the historical data of specified symbol using asynchronous method
        /// </summary>
        /// <param name="targetSymbol"></param>
        public void DownloadStocktHistoricalData(string targetSymbol)
        {
            DataDownloadServiceClient ddsc = new DataDownloadServiceClient();
            ddsc.DoDownLoadCompleted += new EventHandler<DoDownLoadCompletedEventArgs>(ddsc_DoDownLoadCompleted);
            ddsc.DoDownLoadAsync(String.Format(DataDownloadUrlFormats.YahooDailyHistoricalData, targetSymbol), targetSymbol);

            ObservableSymbolItem newDownloadItem = new ObservableSymbolItem { Symbol = targetSymbol, DownloadStatus = SymbolDownloadStatus.Downloading };
            this.EventAggregator.GetEvent<HistoricalDataDownloadStatusChanged>().Publish(newDownloadItem);
        }

        private void ddsc_DoDownLoadCompleted(object sender, DoDownLoadCompletedEventArgs e)
        {
            ObservableSymbolItem finishedDownloadItem = new ObservableSymbolItem { Symbol = e.UserState.ToString() };

            if (e.Error != null)
            {
                if (String.IsNullOrEmpty(e.Error.Message)) MessageBox.Show(e.Error.Message);
                finishedDownloadItem.DownloadStatus = SymbolDownloadStatus.Failed;
            }

            else
            {
                finishedDownloadItem.DownloadStatus = SymbolDownloadStatus.Finshed;
                if (e.Result.Length > 0)
                {
                    _historicalDataList.Add(
                    key: (String)e.UserState,
                    value: HistoricalDataConverter.ConvertFromCSV(e.Result));
                    OnNewHistoricalDataObtained(e.UserState.ToString());
                }
            }
            this.EventAggregator.GetEvent<HistoricalDataDownloadStatusChanged>().Publish(finishedDownloadItem);
        }

        /// <summary>
        /// Load all the historical data from isolated storage
        /// </summary>
        public void LoadAllHistoricalData()
        {
            using (var store = IsolatedStorageFile.GetUserStoreForApplication())
            {
                if (store.DirectoryExists(ISOLATED_STORAGE_DIRECTORY))
                {
                    foreach (string file in store.GetFileNames(Path.Combine(ISOLATED_STORAGE_DIRECTORY, "*")))
                    {
                        if (_historicalDataList.ContainsKey(file)) return;
                        try
                        {
                            using (IsolatedStorageFileStream tempStream = store.OpenFile(Path.Combine(ISOLATED_STORAGE_DIRECTORY, file), FileMode.Open, FileAccess.Read))
                            {
                                if (tempStream.Length > 0)
                                {
                                    StockHistoricalDataCollection collection = new StockHistoricalDataCollection();
                                    collection.ReadBinaryDataFromFile(tempStream);
                                    _historicalDataList.Add(key: file, value: collection);
                                    OnNewHistoricalDataObtained(file);
                                }
                            }
                        }
                        catch (IsolatedStorageException)
                        {
                            MessageBox.Show("Data initializing error! Click OK to skip");
                        }
                    }
                }
            }
        }

        /// <summary>
        /// Save the historical data to isolated storage
        /// </summary>
        /// <param name="targetSymbol">The symbol of data to be saved</param>
        public void SaveHistoricalData(string targetSymbol)
        {
            if (!_historicalDataList.ContainsKey(targetSymbol))
            {
                MessageBox.Show("Data was not found!");
                return;
            }
            using (var store = IsolatedStorageFile.GetUserStoreForApplication())
            {
                if (!store.DirectoryExists(ISOLATED_STORAGE_DIRECTORY)) store.CreateDirectory(ISOLATED_STORAGE_DIRECTORY);
                IsolatedStorageFileStream isfs = store.OpenFile(Path.Combine(ISOLATED_STORAGE_DIRECTORY, targetSymbol), FileMode.Create, FileAccess.Write);
                if (isfs != null) _historicalDataList[targetSymbol].WriteBinaryDataToFile(isfs);
                isfs.Close();
            }
        }
    }
}
